package population;

import java.util.ArrayList;
import java.util.logging.Logger;

import population.populationFindPredicates.PopulationFindPredicate;
import character.Character;

/**
 * Population class.
 * @author pcdejager
 *
 */
public class Population {
    /**
     * Constructor.
     */
    public Population() {
        individuals = new ArrayList<Character>();
    }

    /**
     * Add an individual to the population.
     * @param c The character to add
     */
    public final void addIndividual(final Character c) {
        LOGGER.info(c.toString());
        individuals.add(c);
    }

    /**
     * Check the container to see if the character exist.
     * @param c The character to find
     * @return True if found, else false
     */
    public final boolean contains(final Character c) {
        return individuals.contains(c);
    }

    /**
     * Get the size of the population.
     * @return The number of individuals in the population
     */
    public final int size() {
        return individuals.size();
    }

    /**
     * Remove a character that died.
     * @param c The character that died
     */
    public final void died(final Character c) {
        for (Character i : individuals) {
            i.getSocialLinks().died(c);
        }
        if (individuals.contains(c)) {
            individuals.remove(c);
        }
    }

    /**
     * Count the number of items given a predicate.
     * @param condition The predicate to use
     * @return The number of items found
     */
    public final int count(
            final PopulationFindPredicate condition) {
        int result = 0;
        for (Character c : individuals) {
            if (condition.check(c)) {
                ++result;
            }
        }
        return result;
    }

    /**
     * Find characters in the population given a predicate.
     * @param condition The predicate to use
     * @return The list of characters that were found
     */
    public final ArrayList<Character> find(
            final PopulationFindPredicate condition) {
        ArrayList<Character> result = new ArrayList<Character>();
        for (Character c : individuals) {
            if (condition.check(c)) {
                result.add(c);
            }
        }
        return result;
    }

    /**
     * Find characters in the population given a collection of predicates.
     * @param conditions The array of predicates
     * @return The list of characters that were found
     */
    public final ArrayList<Character> find(
            final PopulationFindPredicate[] conditions) {
        ArrayList<Character> result = new ArrayList<Character>();
        for (Character c : individuals) {
            boolean ok = true;
            for (int count = 0; (count < conditions.length) && (ok); ++count) {
                PopulationFindPredicate p = conditions[count];
                if (!p.check(c)) {
                    ok = false;
                }
            }
            if (ok) {
                result.add(c);
            }
        }
        return result;
    }

    /**
     * The collection of individuals in the population.
     */
    private ArrayList<Character> individuals = null;
    /**
     * Logger.
     */
    private static final Logger LOGGER =
            Logger.getLogger(Population.class.getName());
}
